/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-3-19 21:40:26
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#include "RpcClientMgr.h"
#include "rpc_client_base.h"

CRpcClientMgr::CRpcClientMgr()
{//default 4 threads
    m_netReactor.init_reactor(this, 4);
    m_rpc_clients_map.clear();
}
CRpcClientMgr::CRpcClientMgr(int threadnum)
{
    m_netReactor.init_reactor(this, threadnum);
    m_rpc_clients_map.clear();
}
CRpcClientMgr::~CRpcClientMgr()
{
    m_netReactor.uninit_reactor();
    del_all_rpc_client();
}

void CRpcClientMgr::free()
{
    m_netReactor.uninit_reactor();
    del_all_rpc_client();
}

smart::ref_ptr<CRpcClientBase> CRpcClientMgr::get_rpc_client( SOCK_FD fd )
{
    CRpcClientBase* client = NULL;
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcClientBase> >::iterator it = m_rpc_clients_map.find(fd);
    if( it != m_rpc_clients_map.end() )
    {
        client = (it->second).getPointer();
    }
    return client;
}
int CRpcClientMgr::add_rpc_client( CRpcClientBase* client )
{
    if(client == NULL) return -1;
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcClientBase> >::iterator it = m_rpc_clients_map.find(client->m_clifd);
    if( it != m_rpc_clients_map.end() )
    {
        m_rpc_clients_map.erase(it);
    }
    m_rpc_clients_map[client->m_clifd] = client;
    return 0;
}
int CRpcClientMgr::del_rpc_client( SOCK_FD fd )
{
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcClientBase> >::iterator it = m_rpc_clients_map.find(fd);
    if( it != m_rpc_clients_map.end() )
    {
        m_rpc_clients_map.erase(it);
        return 0;
    }
    return -1;
}
void CRpcClientMgr::del_all_rpc_client()
{
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcClientBase> >::iterator it = m_rpc_clients_map.begin();
    m_rpc_clients_map.clear();
}


int CRpcClientMgr::on_connect( SOCK_FD listen_fd, SOCK_FD cli_fd, const char* remote_ip, int remote_port )
{
    return 0;
}
int CRpcClientMgr::on_data( SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port )
{
    smart::ref_ptr<CRpcClientBase> client = get_rpc_client(fd);
    if(client) {
        client->m_decoder.Parse(fd, data, len);
    } else {
        printf("on_data, but not found in m_rpc_clients_map\n");
    }
    return 0;
}
int CRpcClientMgr::on_send_ack( SOCK_FD fd, int len )
{
    return 0;
}
int CRpcClientMgr::on_close( SOCK_FD fd, int error )
{
    //printf("CRpcClientMgr::on_close fd=[%d], error=[%d]\n", fd, error);
    smart::ref_ptr<CRpcClientBase> client = get_rpc_client(fd);
    if(client) {
        client->on_rpc_close(error);
    }
    del_rpc_client(fd);
    return 0;
}
int CRpcClientMgr::onPDU( int fd, smart::ref_ptr<NetBinaryPdu> pdu )
{
    smart::ref_ptr<CRpcClientBase> client = get_rpc_client(fd);
    if(client) {
        client->on_invoke(pdu);
    }
    return 0;
}
int CRpcClientMgr::onError( int fd, BinaryDecoderError_t err )
{
    printf("client decoder fd[%d], error[%d]\n", fd, err);
    return 0;
}
